import React, { Component } from 'react'
import {
    Card,
    Icon,
    Form,
    Input,
    Cascader,
    Button,
    message
} from 'antd'

import { addOrUpdateProduct, reqCategorys } from '../../api'
import PicturesWall from './pictures-wall'
import RichTextEditor from './rich-text-editor'

const { Item } = Form
const { TextArea } = Input


/**
 * Product的添加和更新的子路由组件
 */
export default class ProductAddUpdate extends Component {

    state = {
        options: []
    }

    constructor(props) {
        super(props)

        // 创建用来保存ref标识的标签对象的容器
        this.pw = React.createRef();
        this.editor = React.createRef();

    }

    onFinish = async values => {
        // console.log('Received values of form: ', values);
        console.log(this.pw.current.getImgs());

        //1. 收集数据
        const { name, desc, price, catIds } = values;

        let pCategoryId, categoryId;
        if (catIds.length === 1) {
            pCategoryId = 0;
            categoryId = catIds[0];
        } else {
            pCategoryId = catIds[0];
            categoryId = catIds[1];
        }

        const imgs = this.pw.current.getImgs();
        const detail = this.editor.current.getDetail();
        const product = { name, desc, price, imgs, detail, pCategoryId, categoryId };

        //如果是更新，需要指定_id
        if (this.isUpdate) {
            product._id = this.product._id;
        }

        //2. 调用接口，去添加、更新
        const result = await addOrUpdateProduct(product);

        //3. 根据结果提示
        if (result.status === 0) {
            message.success(`${this.isUpdate?'更新成功':'保存成功'}`)
            this.props.history.goBack();
        } else {
            message.error(`${this.isUpdate?'更新失败':'保存失败'}`)
        }
    };

    initOptions = async (categorys) => {
        // 根据categorys生成options数组
        const options = categorys.map(c => ({
            value: c._id,
            label: c.name,
            isLeaf: false, // 不是叶子
        }))
        this.setState({
            options
        })
    }

    loadData = async selectedOptions => {

        const targetOption = selectedOptions[0];

        //显示loading
        targetOption.loading = true;

        // 根据选中的分类，请求获取二级分类列表
        const subCategorys = await this.getCategorys(targetOption.value);

        //隐藏loading
        targetOption.loading = false;

        if (subCategorys && subCategorys.length > 0) {
            // 生成一个二级列表的options
            const childOptions = subCategorys.map(c => ({
                value: c._id,
                label: c.name,
                isLeaf: true
            }))

            // 关联到当前option上
            targetOption.children = childOptions
        } else {
            // 当前选中的分类没有二级分类
            targetOption.isLeaf = true;
        }

        // 更新option状态
        this.setState({
            options: [...this.state.options]
        })
    };

    /**
     * 异步获取一级/二级分类列表, 并显示
     * async函数的返回值是一个新的promise对象, promise的结果和值由async的结果来决定
     */
    getCategorys = async (parentId) => {
        const result = await reqCategorys(parentId)   // {status: 0, data: categorys}

        if (result.status === 0) {
            const categorys = result.data
            // 如果是一级分类列表
            if (parentId === '0') {
                // 根据categorys生成options数组
                this.initOptions(categorys)
            } else { // 二级列表
                return categorys  // 返回二级列表 ==> 当前async函数返回的promsie就会成功且value为categorys
            }
        }
    }

    /**
     * 验证价格的自定义验证函数
     */
    validatePrice = (rule, value, callback) => {
        console.log(value, typeof value)
        if (value * 1 > 0) {
            callback() // 验证通过
        } else {
            callback('价格必须大于0') // 验证没通过
        }
    }
    componentWillMount() {
        // 取出携带的state
        const product = this.props.location.state  // 如果是添加没值, 否则有值

        // 保存是否是更新的标识
        this.isUpdate = !!product

        // 保存商品(如果没有, 保存是{})
        this.product = product || {}
    }
    componentDidMount() {
        this.getCategorys('0')
    }
    render() {

        // 指定Item布局的配置对象
        const formItemLayout = {
            labelCol: { span: 2 },  // 左侧label的宽度
            wrapperCol: { span: 6 }, // 右侧包裹的宽度
        }

        // 头部左侧标题
        const title = (
            <span>
                <a href="##" onClick={() => this.props.history.goBack()}>
                    <Icon type='arrow-left' style={{ fontSize: 20 }} />
                </a>
                <span>添加商品</span>
            </span>
        )
        return (
            <Card title={title}>
                <Form {...formItemLayout} onFinish={this.onFinish} size='large'>
                    <Item name="name" label="商品名称" rules={[{ required: true, message: '必须输入商品名称' }]}>
                        <Input placeholder='请输入商品名称'></Input>
                    </Item>
                    <Item name="desc" label="商品描述" rules={[{ required: true, message: '必须输入商品描述' }]}>
                        <TextArea placeholder="请输入商品描述" autosize={{ minRows: 3, maxRows: 6 }} />
                    </Item>
                    <Item label="商品价格" name="price" rules={[{ required: true, message: '必须输入商品价格' }, { validator: this.validatePrice }]}>
                        <Input type='number' placeholder='请输入商品价格' addonAfter='元' />
                    </Item>
                    <Item label="商品分类" name="catIds">
                        <Cascader
                            placeholder='请指定商品分类'
                            options={this.state.options}  /*需要显示的列表数据数组*/
                            loadData={this.loadData} /*当选择某个列表项, 加载下一级列表的监听回调*/
                        />
                    </Item>
                    <Item label="商品图片" name="imgs">
                        <PicturesWall ref={this.pw}></PicturesWall>
                    </Item>
                    <Item label="商品详情" name="detail" labelCol={{ span: 2 }} wrapperCol={{ span: 20 }}>
                        <RichTextEditor ref={this.editor} />
                    </Item>
                    <Item>
                        <Button type='primary' htmlType="submit">提交</Button>
                    </Item>
                </Form>
            </Card>
        )
    }
}